<template>
  <div class="js-plumb-container-wrap" ref="jsPlumbContainerWrap">
    <div class="js-plumb-container" ref="jsPlumbContainer">
      <div class="jsp-container-scale" ref="jsPlumbContainerScale">
        <div id="itemContainer" class="itemContainer" ref="itemContainer"></div>
      </div>

    </div>
    <div class="page-tool-box-warp" v-if="isShowTools">
      <div class="btn plus" @click="handleClick('plus')">
        <i class="iconfont icon-fangda"></i>
      </div>
      <div class="btn" @click="handleClick('minus')">
        <i class="iconfont icon-fangda1"></i>
      </div>
    </div>
    <div class="dialog-jsPlumb" v-if="!isOperable"></div>

    <div class="show-container-wrap" ref="showContainer">
      <div class="show-js-plumb-container" ref="showJsPlumbContainer">

      </div>
      <div class="show-area" ref="showArea" @mousedown="dragMouseDown" @mouseup="dragMouseUp"></div>
    </div>
  </div>

</template>

<script>
  import ProcessConfig from '@/views/screenConfig/dataSet/components/mixin/processConfig'
  import { startCommon, endCommon } from './components/commonData'
  import { deepClone } from '@/utils'

  const scale = 20 //缩略图比率

  export default {
    name: 'index',
    mixins: [ProcessConfig],
    props: {
      formData: {
        type: String
      },
      isOperable: {
        type: Boolean,
        default: false
      },
      isShowTools: {
        type: Boolean,
        default: true
      }
    },
    data() {
      return {
        viewWidth: '0',
        viewHeight: '0',
        zoom: 1,
        jsPlumbContainerWrap: null,
        jsPlumbContainer: null,
        jsPlumbContainerScale: null,
        showContainer: null,
        showArea: null,
        showJsPlumbContainer: null
      }
    },
    watch: {
      formData: {
        handler: function(val) {
          this.initData()
          this.initDom()
        }
      },
      zoom: {
        handler: function(val) {
          this.copyDom()
        }
      }
    },
    methods: {
      /**
       * 添加锚点
       * @params dom 元素
       * @params uuid 唯一标识
       * @params position 位置 left || right
       */
      addEndpoint(dom, uuid, position) {
        let _this = this
        this.jsPlumbObj.addEndpoint(dom, {
          anchor: _this.getAnchor(position, 1),
          uuid
        }, position === 'Right' ? startCommon : endCommon)
      },
      /**
       * 创建节点node
       * @param nodeData
       */
      createFlowDom(nodeData) {
        return nodeData ? `<div class="node-item-warp" data-type="${nodeData.type}">
                    <div class="node-item-title">
                      <span>${nodeData.label}</span>
                    </div>` +
          (nodeData.remark ? `<div class="node-item-remark">
                        <span class="remark">${nodeData.remark}</span>
                    </div>` : '<div></div>') +
          `</div>` : '<div></div>'
      },
      /**
       * 创建节点dom以及修改样式
       */
      setDomStyle(config) {
        let flowDom = document.createElement('div')
        flowDom.innerHTML = this.createFlowDom(config)
        flowDom.classList.add('d-s-flow-item-container')
        flowDom.classList.add('d-s-flow-item-container-show')
        flowDom.id = config.id
        flowDom.type = config.type
        flowDom.style.left = `${config.position.left}px`
        flowDom.style.top = `${config.position.top}px`

        return flowDom
      },
      /**
       * 放大缩小dom元素
       * @param type
       */
      handleClick(type) {
        if (type === 'plus') {
          this.zoom = this.zoom === 1 ? 1 : (this.zoom * 100 + 10) / 100
        } else if (type === 'minus') {
          this.zoom = this.zoom === 0.1 ? 0.1 : (this.zoom * 100 - 10) / 100
        }
        this.jsPlumbContainerScale.style.transform = `scale(${this.zoom})`
      },
      /**
       * 缩略图展示区域移动事件
       */
      dragMouseDown() {
        let { offsetLeft, offsetTop } = document.getElementsByClassName('show-area')[0],
          { width, height } = this.showArea.getBoundingClientRect(),
          { width: cWidth, height: cHeight } = this.showContainer.getBoundingClientRect()
        // console.log(width,height,cWidth,cHeight)
        let oldPageX, oldPageY
        document.onmousedown = event => {
          oldPageX = event.pageX
          oldPageY = event.pageY
        }
        document.onmousemove = event => {
          let offsetPageX = offsetLeft + event.pageX - oldPageX,
            offsetPageY = offsetTop + event.pageY - oldPageY

          if (offsetPageX >= 0 && offsetPageX + width <= cWidth) {
            this.showArea.style.left = `${offsetPageX}px`
            this.jsPlumbContainerScale.style.left = `-${offsetPageX * scale}px`
          }
          if (offsetPageY >= 0 && offsetPageY + height <= cHeight) {
            this.showArea.style.top = `${offsetPageY}px`
            this.jsPlumbContainerScale.style.top = `-${offsetPageY * scale}px`
          }
        }
        document.onmouseup = event => {
          this.dragMouseUp()
        }
      },

      dragMouseUp() {
        document.onmousemove = null
        document.onmouseup = null
      },

      // ---------------------- 数据初始化 ----------------------
      initData() {
        try {
          let { lineData, nodeData } = JSON.parse(this.formData)
          this.nodeData = nodeData
          this.nodeData.forEach(n => {
            this.addFlowItem({ ...n })
          })
          lineData.forEach(l => {
            let sourceInfo = `${l.left}_Right`
            let targetInfo = `${l.right}_Left`
            this.addLine([sourceInfo, targetInfo])
          })
          // this.globalVariableArray = variable ? variable : []
        } catch (e) {
          console.error('JSON转换异常: ', e)
        }
      },

      copyDom() {

        let dom = document.getElementsByClassName('scale-style')
        if (dom && dom.length) {
          dom[0].remove()
        }

        let copyDom = this.$refs.jsPlumbContainerScale.cloneNode(true)
        copyDom.classList.add('scale-style')
        copyDom.style.zoom = 1 / scale
        // copyDom.style.transform = `scale(${this.zoom / 20})`
        this.showJsPlumbContainer.appendChild(copyDom)
      },

      initDom() {
        this.jsPlumbContainerWrap = this.$refs.jsPlumbContainerWrap
        this.jsPlumbContainer = this.$refs.jsPlumbContainer
        this.jsPlumbContainerScale = this.$refs.jsPlumbContainerScale
        this.showJsPlumbContainer = this.$refs.showJsPlumbContainer

        this.showArea = this.$refs.showArea
        this.showContainer = this.$refs.showContainer

        let { width, height } = this.jsPlumbContainerWrap.getBoundingClientRect()
        let { width: cWidth, height: cHeight } = this.jsPlumbContainer.getBoundingClientRect()

        this.$nextTick(() => {

          this.showContainer.style.width = `${cWidth / scale}px`
          this.showContainer.style.height = `${cHeight / scale}px`

          this.showArea.style.width = `${width / scale}px`
          this.showArea.style.height = `${height / scale}px`

          this.copyDom()
        })
      },
    },
    mounted() {
      this.initDom()
    }
  }
</script>

<style scoped lang="scss">
  .js-plumb-container-wrap {
    width: 100%;
    height: 100%;
    overflow: hidden;
    position: relative;
    background-color: #FFFFFF;
    /*background-color: #0c74d5;*/
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;

    .show-container-wrap {
      position: absolute;
      bottom: 4px;
      right: 4px;
      background-color: #ffffff;
      z-index: 999;
      border: 1px solid #53A1D4;
      border-radius: 6px;
      box-shadow: 0 2px 12px 0 rgb(83, 161, 212, .4);

      .show-js-plumb-container {
        width: 100%;
        height: 100%;
        position: relative;
      }

      .show-area {
        background-color: #FFEC3E;
        z-index: 9999;
        position: absolute;
        left: 0;
        top: 0;
        opacity: .4;
        border-radius: 3px;
        transition: all 50ms;
      }
    }

    .js-plumb-container {
      width: 1800px;
      height: 1000px;
      position: relative;
      z-index: 1;

      .jsp-container-scale {
        width: 100%;
        height: 100%;
        position: absolute;
        left: 0;
        top: 0;
        transition: all 50ms;

        .itemContainer {
          width: 100%;
          height: 100%;
          position: relative;

          ::v-deep .jtk-endpoint {
            z-index: 99;
          }
        }
      }
    }

    .itemContainer {
      width: 100%;
      height: 100%;
      position: relative;

      ::v-deep .jtk-endpoint {
        z-index: 99;
      }
    }

    .dialog-jsPlumb {
      position: absolute;
      width: 100%;
      height: 100%;
      top: 0;
      left: 0;
      z-index: 99;
      background-color: transparent;
    }

    .page-tool-box-warp {
      position: absolute;
      bottom: 10px;
      left: 8px;
      display: flex;
      flex-direction: column;
      z-index: 199;
      background-color: #FFFFFF;
      border: 1px solid #eee;
      box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);

      .btn {
        width: 24px;
        height: 30px;
        display: flex;
        justify-content: center;
        align-items: center;
        background-color: #FFFFFF;
        cursor: pointer;

        i {
          font-size: 12px;
        }
      }

      .plus {
        border-bottom: 1px solid #eeeeee;
      }
    }
  }
</style>

<style lang="scss">
  .d-s-flow-item-container-show {
    min-width: 0 !important;

    .anchor-warp {
      opacity: 0 !important;
    }
  }

  .node-item-warp {
    font-size: 14px;
    color: #303133;
    border: 2px solid #53A1D4;
    padding: 8px 12px;
    border-radius: 8px;
    background-color: #F5F9FE;

    .node-item-title {
      color: #303133;
      word-break: keep-all;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      background-color: #F5F9FE;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;

      .title {

      }
    }

    .node-item-remark {
      color: #575757;
      padding-top: 4px;
    }
  }

  .scale-style {
    width: 100%;
    height: 100%;
  }
</style>
